|
このテクニカルノートでは、QuickTime 6 に導入された ImageCodec 'DITL' API について説明します。これらの関数によって、圧縮コンポーネントで Standard Image-Compression Dialog 内に直接表示する、コーデック固有のオプションのためのユーザインタフェースを提供できます。
また、Standard Image-Compression Dialog から品質スライダコントロールを消す方法についても説明します。 [2003 年 5 月 20 日] |
はじめに
Standard Image-Compression Dialog コンポーネントは、イメージまたはイメージシーケンスの圧縮を制御するパラメータを指定するための、一貫性のあるユーザインタフェースを提供します。ユーザは、表示されたダイアログを使って、圧縮コンポーネント、処理するピクセルの深さ、要求する空間的品質を選択できます。また、イメージシーケンスを圧縮するときには、フレームレート、キーフレームレート、データレートを選択できます。
これらの設定に加えて、選択した圧縮コンポーネントにコーデック固有のオプションがある場合は、図 1 に示すように Standard Compression の中から、固有の「オプション」ダイアログにそれらの設定が表示されます。
これは、ImageCodecRequestSettings 関数と、それに対応する ImageCodecGetSettings 関数および ImageCodecSetSettings 関数を実装する圧縮コンポーネントによって行われます。
 |
 |
図 1. 圧縮設定とコーデック固有のオプション
|
QuickTime 6 では、ImageCodecRequestSettings に加えて実装して、図 2 に示すようにより使い勝手の良い「圧縮設定」ユーザインタフェースを提供できる一連の API が導入されています。新しい ImageCodec 'DITL' 関数群が追加されたことで、圧縮コンポーネントはコーデック固有のオプションのユーザインタフェース項目を、Standard Image-Compression Dialog 内に埋め込んで表示できるようになりました。これにより、「オプション」ボタンと追加のオプションダイアログボックスは必要なくなります。
図 2. 埋め込まれたコーデック固有のオプション
|
圧縮コンポーネントを実装するときに、Standard Image-Compression Dialog でコーデック固有のオプションをどのように提示するかを選択できます。
ImageCodecRequestSettings を実装する - これはカスタム設定を有するコーデックで必須の標準関数です。Standard Image-Compression Dialog には「オプション」ボタンが表示され、図 1 に示すようにコーデック固有の圧縮設定を管理するダイアログボックスを表示するための、コーデックの ImageCodecRequestSettings 関数が呼び出されます。
ImageCodecRequestSettings のほかに、ImageCodecGetDITLForSize および関連 API を実装する - これは QuickTime 6 以降で利用できる新しい選択肢です。「オプション」ボタンが削除され、Standard Compression によって、図 2 に示すように、Standard Image-Compression Dialog に埋め込むすべての項目を指定するダイアログ項目リスト ('DITL ') を要求する、コーデックの ImageCodecGetDITLForSize 関数が呼び出されます。
さらに、図 3 に示すように品質スライダコントロールを消せるようにもなりました。圧縮コンポーネントが可逆圧縮 (codecLosslessQuality ) のみを実行する場合は、このコントロールを消してもかまいません。
図 3. 品質スライダの削除
|
本稿では、各 ImageCodec 'DITL' 関数について説明し、それぞれの実装例を紹介するほか、Standard Image-Compression Dialog から品質スライダコントロールを消す方法について説明します。
実装例では、チェックボックスとポップアップメニューコントロールを提供する方法を示します。この実装例は、圧縮コンポーネントに新しい ImageCodec API のサポートを簡単に追加するための出発点として利用できます。
注意:
本稿では、Standard Compression がこれらの新しい ImageCodec API とどのようにやり取りをするかについて説明しますが、ImageCodecRequestSettings を簡単に実装する方法として、これらの API を直接呼び出すこともできます。
|
先頭に戻る
ImageCodec 'DITL' ディスパッチセレクタ
Standard Image-Compression Dialog にコーデック固有の設定を埋め込むには、新しい 6 つのセレクタをすべて実装する必要があります。これらのセレクタは、コーデックのコンポーネントディスパッチファイルの Range 1 に追加します。
リスト 1. ImageCodec.h の ImageCodec セレクタ
| kImageCodecGetDITLForSizeSelect = 0x002E
kImageCodecDITLInstallSelect = 0x002F
kImageCodecDITLEventSelect = 0x0030
kImageCodecDITLItemSelect = 0x0031
kImageCodecDITLRemoveSelect = 0x0032
kImageCodecDITLValidateInputSelect = 0x0033
|
リスト 2. コンポーネントディスパッチャ
| ComponentComment ("Codec Range")
ComponentRangeBegin (1)
ComponentCall (GetCodecInfo)
.
. ...Various other Codec Range 1 selectors
.
ComponentCall (GetDITLForSize)
ComponentCall (DITLInstall)
ComponentCall (DITLEvent)
ComponentCall (DITLItem)
ComponentCall (DITLRemove)
ComponentCall (DITLValidateInput)
ComponentRangeEnd (1)
|
先頭に戻る
ImageCodec 'DITL' 関数
ImageCodecGetDITLForSize
ComponentResult ImageCodecGetDITLForSize(ComponentInstance ci,
Handle *ditl,
Point *requestedSize)
|
ditl - ハンドルへのポインタ。ダイアログ項目はここに返されます。
requestedSize - ダイアログに収まる、要求されたサイズ(ピクセル単位)。
エラーがない場合は noErr 、サイズがサポートされていない場合は badComponentSelector を返します。
|
圧縮コンポーネントが選択されると、Standard Compression によって、ImageCodecGetDITLForSize が呼び出されて、コーデックは指定のピクセル数に収まるユーザインタフェース要素 (ダイアログ項目リスト 'DITL ') を提供するよう求められます。
サイズパラメータに渡される特殊な値に、kSGSmallestDITLSize と kSGLargestDITLSize という 2 つの値があります。これらの特殊な値はそれぞれ、項目の最小サイズと最大サイズを要求するものです。少なくとも kSGSmallestDITLSize をサポートし、コンポーネントによって提供されないサイズの場合は、badComponentSelector を返す必要があります。
Standard Compression では現在のところ、kSGSmallestDITLSize のみが要求されます。
適切なダイアログ項目リストを返すことに成功すると、圧縮コンポーネントは引き続いてこの項目の管理のために呼び出されます。返すハンドルは、リソースマネージャハンドルであってはなりません。
リスト 3. 'DITL ' の実装例と関連リソース
| #define kMyCodecDITLResID 129
#define kMyCodecPopupCNTLResID 129
#define kMyCodePopupMENUResID 129
#define TEXT_HEIGHT 16
#define INTER_CONTROL_SPACING 12
#define POPUP_CONTROL_HEIGHT 22
resource 'DITL' (kMyCodecDITLResID, "Compressor Options") {
{
{0, 0, TEXT_HEIGHT, 100},
CheckBox { enabled, "Checkbox" },
{TEXT_HEIGHT + DIALOG_CONTROL_SPACING, 0,
TEXT_HEIGHT + DIALOG_CONTROL_SPACING + POPUP_CONTROL_HEIGHT, 165},
Control { enabled, kMyCodecPopupCNTLResID },
};
};
resource 'CNTL' (kMyCodecPopupCNTLResID, "Compressor Popup") {
{0, 0, 20, 165},
0,
visible,
60, /* タイトルの幅 */
kMyCodecPopupMENUResID,
popupMenuCDEFProc+popupFixedWidth,
0,
"Menu:"
};
resource 'MENU' (kMyCodePopupMENUResID, "Compressor Popup") {
kMyCodePopupMENUResID,
textMenuProc,
0x7FFD, /* フラグを有効化 */
enabled,
"Popup",
{ /* 配列:8 個の要素 */
/* [1] */
"Best", noIcon, noKey, noMark, plain,
/* [2] */
"-", noIcon, noKey, noMark, plain,
/* [3] */
"None", noIcon, noKey, noMark, plain,
/* [4] */
"Less", noIcon, noKey, noMark, plain,
/* [5] */
"Some", noIcon, noKey, noMark, plain,
/* [6] */
"More", noIcon, noKey, noMark, plain,
/* [7] */
"Many", noIcon, noKey, noMark, plain,
/* [8] */
"Most", noIcon, noKey, noMark, plain
}
};
|
リスト 4. ImageCodecGetDITLForSize の実装
| // 項目番号
//
#define kItemCheckbox 1
#define kItemPopup 2
pascal ComponentResult MyCodec_GetDITLForSize(Handle storage,
Handle *ditl,
Point *requestedSize)
{
Globals *store = (Globals *)storage;
Handle h = NULL;
ComponentResult err = noErr;
switch (requestedSize->h) {
case kSGSmallestDITLSize:
GetComponentResource((Component)(store->self), FOUR_CHAR_CODE('DITL'),
kMyCodecDITLResID, &h);
if (NULL != h) *ditl = h;
else err = resNotFound;
break;
default:
err = badComponentSelector;
break;
}
return err;
}
|
先頭に戻る
ImageCodecDITLInstall
ComponentResult ImageCodecDITLInstall(ComponentInstance ci,
DialogRef d,
short itemOffset)
|
d - 圧縮設定ダイアログボックスを示すダイアログ参照。コンポーネントはこの値を使用して、ダイアログボックスの一部を管理します。
itemOffset - イメージコーデックの最初の項目へのオフセット。
エラーが発生しなかった場合は、noErr を返します。
|
Standard Compression では、ダイアログ項目が Standard Image-Compression Dialog に追加されたあと、ユーザに対して表示される前に、ImageCodecDITLInstall が呼び出されます。コンポーネントには、項目の埋め込み先のダイアログへの参照と、ダイアログに表示される最初の項目へのオフセットが渡されます。この呼び出しの前に ImageCodecSetSettings が呼び出されるため、この機会を利用してデフォルト値の設定や、コントロール値の初期化を行います。
項目は、他の項目が含まれているダイアログボックスに組み込まれるため、コンポーネントが呼び出されるたびに、itemOffset 値が異なる可能性があります。この値が常に同じであると想定しないでください。
リスト 5. ImageCodecDITLInstall の実装
| pascal ComponentResult MyCodec_DITLInstall(Handle storage,
DialogRef d,
short itemOffset)
{
ControlRef cRef;
unsigned long checkboxValue = (**storage).checkboxPreference;
unsigned long popupValue = (**storage).popupPreference;
GetDialogItemAsControl(d, kItemCheckBox + itemOffset, &cRef);
SetControl32BitValue(cRef, checkboxValue);
GetDialogItemAsControl(d, kItemPopup + itemOffset, &cRef);
SetControl32BitValue(cRef, popupValue);
return noErr;
}
|
先頭に戻る
ImageCodecDITLEvent
ComponentResult ImageCodecDITLEvent(ComponentInstance ci,
DialogRef d,
short itemOffset,
const EventRecord *theEvent,
short *itemHit,
Boolean *handled)
|
d - 圧縮設定ダイアログボックスを示すダイアログ参照。
itemOffset - ダイアログボックスにおけるイメージコーデックの最初の項目へのオフセット。
theEvent - EventRecord 構造体へのポインタ。この構造体には、イベントの性質を示す情報が含まれています。
itemHit - コンポーネントがイベントを処理する場合に項目番号を受け取るフィールドへのポインタ。返される番号は絶対番号であって、相対番号ではないため、itemOffset パラメータによってオフセットする必要があります。
handled - ブール値へのポインタ。イベントを処理する場合は、このブール値を true に設定します。イベントを処理しない場合は、false に設定します。
エラーが発生しなかった場合は、noErr を返します。
|
ImageCodecDITLEvent は、Standard Image-Compression Dialog イベントフィルタの一部として呼び出されます。そのため、コンポーネントは、標準ダイアログイベントフィルタによって受け取られたけれども、処理されなかったすべてのイベントをフィルタリングすることで、イベントソースに近いところでイベントを制御および処理できます。
たとえば、ユーザによるキーの押下を独自の項目にマップしたい場合は、このレベルでイベントを処理できます。
コンポーネントでイベントを処理する場合は、handled を true に、itemHit をヒットされた項目の絶対項目番号に設定します。コンポーネントでイベントを処理しない場合は、handled を false に設定し、itemHit はそのままにします。
絶対項目番号は、itemOffset 値でオフセットする必要があります。たとえば、渡された itemOffset が 4 で、ヒットされた項目が最初の項目だった場合、返される絶対値は itemOffset と項目番号を加算して 5 (4+1=5) になります。
リスト 6. ImageCodecDITLEvent の実装
| pascal ComponentResult MyCodec_DITLEvent(Handle storage,
DialogRef d,
short itemOffset,
const EventRecord *theEvent,
short *itemHit,
Boolean *handled)
{
*handled = false;
return noErr;
}
|
先頭に戻る
ImageCodecDITLItem
ComponentResult ImageCodecDITLItem(ComponentInstance ci,
DialogRef d,
short itemOffset,
short itemNum)
|
d - 設定ダイアログボックスを示すダイアログ参照。
itemOffset - ダイアログボックスにおけるパネルの最初の項目へのオフセット。
itemNum - ユーザが選択したダイアログ項目の項目番号。
エラーが発生しなかった場合は、noErr を返します。
|
ImageCodecDITLItem は、項目の 1 つがヒットされたときに、Standard Image-Compression Dialog イベント処理手続きの一環として呼び出されます。コンポーネントでは、ヒットされた項目番号に応じて適切な処理を実行できます。
itemNum パラメータは絶対番号です。この値は、ダイアログボックスにおける最初の項目へのオフセットを考慮して調整する必要があります。
たとえば、渡された itemNum が 5 で、itemOffset が 4 の場合、5-4 = 1 であるため、これはコンポーネントの最初の項目がヒットされたことを示します。
リスト 7. ImageCodecDITLItem の実装
|
pascal ComponentResult MyCodec_DITLItem(Handle storage,
DialogRef d,
short itemOffset,
short itemNum)
{
ControlRef cRef;
switch (itemNum - itemOffset) {
case kItemCheckbox:
GetDialogItemAsControl(d, itemOffset + kItemCheckbox, &cRef);
SetControl32BitValue(cRef, !GetControl32BitValue(cRef));
break;
case kItemPopup:
break;
}
return noErr;
}
|
先頭に戻る
ImageCodecDITLRemove
ComponentResult ImageCodecDITLRemove(ComponentInstance ci,
DialogRef d,
short itemOffset)
|
d - 設定ダイアログボックスを示すダイアログポインタ。
itemOffset - ダイアログボックスの最初の項目へのオフセット。
エラーが発生しなかった場合は、noErr を返します。
|
Standard Compression では、項目の削除と設定ダイアログの破棄の直前に、設定を完了する過程で ImageCodecDITLRemove が呼び出されます。コンポーネントには、項目の埋め込み先となるダイアログへの参照と、ダイアログに表示される最初の項目へのオフセットが渡されます。
この機会を利用して、コーデック固有の項目の状態に従って、コーデックのグローバルに適切な値を設定できます。ImageCodecDITLValidateInput (後述)の ok パラメータを true に設定した場合は、Standard Compression によって ImageCodecDITLRemove の直後に ImageCodecGetSettings が呼び出され、現在の設定が取得されます。
リスト 8. ImageCodecDITLRemove の実装
|
pascal ComponentResult MyCodec_DITLRemove(Handle storage,
DialogRef d,
short itemOffset)
{
ControlRef cRef;
unsigned long checkboxValue;
unsigned long popupValue;
GetDialogItemAsControl(d, kItemCheckbox + itemOffset, &cRef);
checkboxValue = GetControl32BitValue(cRef);
GetDialogItemAsControl(d, kItemPopup + itemOffset, &cRef);
popupValue = GetControl32BitValue(cRef);
(**storage).checkboxPreference = checkboxValue;
(**storage).popupPreference = popupValue;
return noErr;
}
|
先頭に戻る
ImageCodecDITLValidateInput
ComponentResult ImageCodecDITLValidateInput(ComponentInstance ci,
Boolean *ok)
|
ok - ブール値へのポインタ。設定が OK であれば、この値を true に設定します。OK でない場合は、false に設定します。
エラーが発生しなかった場合は、noErr を返します。
|
設定の選択を完了する過程でユーザが「OK」ボタンをクリックすると、Standard Compression によって ImageCodecDITLValidateInput が呼び出されます。ユーザが「キャンセル」ボタンをクリックすると、コンポーネントはこの呼び出しを受け取りません。
コンポーネント側ではこの呼び出しを利用して、設定を確認し、設定が有効かどうかを示すことができます。
ok パラメータに true を設定して有効な設定であることを示すと、Standard Compression によって ImageCodecDITLRemove と ImageCodecGetSettings が呼び出され、現在の圧縮設定が取り出されます。ok を false に設定すると、Standard Compression によって「OK」ボタンが無視され、ImageCodecDITLRemove を呼び出した後で現在の圧縮設定は要求されません。
リスト 9. ImageCodecDITLValidateInput の実装
| pascal ComponentResult MyCodec_DITLValidateInput(Handle storage,
Boolean *ok)
{
if (ok)
*ok = true;
return noErr;
}
|
先頭に戻る
品質スライダの削除
コーデックの中で、新しく導入された ImageCodec 'DITL' 関数群を実装すると、「オプション」ボタンは自動的に消えますが、「品質スライダ」コントロールは、kCodecCompressionNoQuality フラグを含むコーデックコンポーネントオプションリソース ('ccop ') を含めることによって消します。この 'ccop ' リソースは、コンポーネントのパブリックリソースリスト ('thnr ' リソース) から参照する必要があります。
リスト 10. 品質スライダコントロールの消去
| #define kCodecCompressionNoQuality 0x00000001
type 'ccop' {
longint;
};
resource 'thnr' (kMyCodecThingResID) {
{
'cdci', 1, 0,
'cdci', kMyCodeccdciResID, 0,
'ccop', 1, 0,
'ccop', kMyCodecThingResID, 0,
}
};
resource 'ccop' (kMyCodecThingResID) {
kCodecCompressionNoQuality;
};
|
先頭に戻る
参考資料
About Standard Image-Compression Dialog Components
The Standard Image-Compression Dialog
QuickTime の最新情報
先頭に戻る
|